import math
print(int('123'), str(123), float('123.45'))


def nop():
    pass


def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x


print('绝对值为', my_abs(-5))


def quadratic(a, b, c):
    delta = b ** 2 - 4 * a * c
    if delta < 0:
        print('无实根')
    elif delta == 0:
        return (-b + math.sqrt(b**2 - 4 * a * c))/(2 * a)
    elif delta > 0:
        return (-b + math.sqrt(b**2 - 4 * a * c))/(2 * a),\
            (-b - math.sqrt(b**2 - 4 * a * c))/(2 * a)
# 注意return的两个数用逗号隔开


result = (1.0, -1.0)
if result == quadratic(1, 0, -1):
    print(result)  # 求二元一次方程的根，输出(1.0, -1.0)


# 默认参数可以简化函数的调用。设置默认参数时，有几点要注意：
# 一是必选参数在前，默认参数在后，否则Python的解释器会报错。
# 二是如何设置默认参数。
# 当函数有多个参数时，把变化大的参数放前面，变化小的参数放后面。变化小的参数就可以作为默认参数。


def power(x, n=2):
    result = 1
    while n > 0:
        result = result * x
        n = n - 1
    return result


print(power(5), power(5, 3))  # 输出25 125

# 默认参数很有用，但使用不当，也会掉坑里。默认参数有个最大的坑，演示如下：


def add_end(L=[]):
    L.append('END')
    return L


print(add_end([1, 2, 3]))  # 输出[1, 2, 3, 'END']
print(add_end())  # 输出['END']
print(add_end())  # 输出['END', 'END']
# 默认参数L也是一个变量，它指向对象[]，如果改变了L的内容，则下次调用时，还会修改这个[]
# 因此，定义默认参数要牢记一点：默认参数必须指向不变对象！可以这样写
# def add_end(L=None):
#     if L is None:
#         L = []
#     L.append('END')
#     return L

# 在Python函数中，还可以定义可变参数。顾名思义，可变参数就是传入的参数个数是可变的，可以是1个、2个到任意个，还可以是0个。
# 我们以数学题为例子，给定一组数字a，b，c……，请计算a2 + b2 + c2 + ……。
# 要定义出这个函数，我们必须确定输入的参数。由于参数个数不确定，我们首先想到可以把a，b，c……作为一个list或tuple传进来


def calc_old(numbers):
    result = 1
    for num in numbers:
        result = result * num
    return result


nums = (2, 3, 4)

print('2*3*4 =', calc_old(nums))  # 使用一个tuble来传递参数，结果输出24
# 如果利用可变参数，可以不用把数据事先封装为tuble，想传递几个参数就传递几个参数：


def calc(*numbers):
    result = 1
    for num in numbers:
        result = result * num
    return result


print('2*3*4 =', calc(2, 3, 4))  # 使用可变参数来传递参数，结果输出24
print('2*3*4 =', calc(*nums))    # 可变参数的函数也可以使用tuble来传递参数，结果还是输出24

# 关键字参数允许你传入0个或任意个含参数名的参数，这些关键字参数在函数内部自动组装为一个dict。请看示例：


def person(name, age, **kw):
    if 'city' in kw:
        # 有city参数
        pass
    if 'job' in kw:
        # 有job参数
        pass
    print('name:', name, 'age:', age, 'other:', kw)


person('Lemon', 24, city='广州', job='学生')
# 输出name: Lemon age: 24 other: {'city': '广州', 'job': '学生'} 可见关键字参数变为了dict

# 和关键字参数**kw不同，命名关键字参数需要一个特殊分隔符*，*后面的参数被视为“命名”关键字参数。
# 即输入参数的时候，必须有xx=xxx


def person_1(name, age, *, city, job):
    print(name, age, city, job)


person_1('Jack', 24, city='Beijing', job='Engineer')
# 输出Jack 24 Beijing Engineer
